package cn.iocoder.ny.module.mall.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONString;
import cn.iocoder.ny.module.mall.controller.admin.order.vo.MallOrderVo;
import cn.iocoder.ny.module.mall.controller.admin.product.dto.MallProductListDTO;
import cn.iocoder.ny.module.mall.domain.*;
import cn.iocoder.ny.module.mall.domain.vo.MallWeChatPayVo;
import cn.iocoder.ny.module.mall.mapper.MallOrderDetailsMapper;
import cn.iocoder.ny.module.mall.mapper.MallOrderMapper;
import cn.iocoder.ny.module.mall.processor.OrderD;
import cn.iocoder.ny.module.mall.processor.OrderProcessor;
import cn.iocoder.ny.module.mall.service.*;
import cn.iocoder.ny.module.mall.utils.wxpay.IdUtils;
import cn.iocoder.ny.module.mall.utils.wxpay.ResultModel;
import cn.iocoder.ny.module.mall.utils.wxpay.WxPayUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.system.dal.dataobject.system.SystemUsers;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
import cn.iocoder.yudao.module.system.service.system.ISystemUserService;
/**
 * @author luchunhong
 * @date 2024/10/27/ 13:59
 * @description:
 */
@Slf4j
@Service
public class IMallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder> implements IMallOrderService {

    private final OrderProcessor orderProcessor;
    private final MallOrderMapper mallOrderMapper;
    private final MallOrderDetailsMapper mallOrderDetailsMapper;
    private final MallProductServiceImpl mallProductService;
    private final MallProductSpecificationSerivceImpl mallProductSpecificationSerivce;
    private final IMallWxPayService iMallWxPayService;
    private final IMallUserService iMallUserService;

    private final ISystemUserService iSystemUserService;

    private final IMallProductSpecificationSerivce iMallProductSpecificationSerivce;

    private final IMallOrderDetailService iMallOrderDetailService;


    @Autowired
    public IMallOrderServiceImpl(OrderProcessor orderProcessor, MallOrderMapper mallOrderMapper, MallOrderDetailsMapper mallOrderDetailsMapper, MallProductServiceImpl mallProductService, MallProductSpecificationSerivceImpl mallProductSpecificationSerivce, IMallWxPayService iMallWxPayService, IMallUserService iMallUserService, ISystemUserService iSystemUserService, IMallProductSpecificationSerivce iMallProductSpecificationSerivce, IMallOrderDetailService iMallOrderDetailService) {
        this.orderProcessor = orderProcessor;
        this.mallOrderMapper = mallOrderMapper;
        this.mallOrderDetailsMapper = mallOrderDetailsMapper;
        this.mallProductService = mallProductService;
        this.mallProductSpecificationSerivce = mallProductSpecificationSerivce;
        this.iMallWxPayService = iMallWxPayService;
        this.iMallUserService = iMallUserService;
        this.iSystemUserService = iSystemUserService;
        this.iMallProductSpecificationSerivce = iMallProductSpecificationSerivce;
        this.iMallOrderDetailService = iMallOrderDetailService;
    }





    @Override
    public PageResult<MallOrder> getMallOrderpage(MallOrderVo mallOrderVo) {

        return mallOrderMapper.selectPage(mallOrderVo);
    }

    @Override
    public PageResult<HashMap<String,Object>> getMallOrderPageMap(MallOrderVo mallOrderVo) {

        return mallOrderMapper.getMallOrderPageMapPR(mallOrderVo);
    }

    @Override
    public List<HashMap<String,Object>> getMallOrderList(MallOrderVo mallOrderVo, Long userid) {



        return mallOrderMapper.getMallOrderList(mallOrderVo);
    }


    //订单列表
    @Override
    public IPage<HashMap<String,Object>> selectPageByMap(HashMap<String,Object> hashMap, Long userid) {
        // Page<Map<String, Object>> page = new Page<>(currentPage, pageSize);
        Long t = Long.valueOf(hashMap.get("tenantid").toString());//前端传
        Long currentpage = Long.valueOf(hashMap.get("currentpage").toString());
        Integer pagesize = Integer.valueOf(hashMap.get("pagesize").toString());

        Page<HashMap<String, Object>> page = new Page<>(currentpage, pagesize);
        hashMap.put("userid",userid);

        IPage<HashMap<String, Object>> result = mallOrderMapper.selectPageByMap(page,hashMap);
        if (result != null && result.getRecords() != null) {
            for (HashMap<String, Object> record : result.getRecords()) {
                if (record.containsKey("create_time")) {
                    LocalDateTime createTime = (LocalDateTime) record.get("create_time");
                    String createTimeStr = createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    record.put("create_time_txt", createTimeStr);

                }

            }
        }
        //return mallOrderMapper.selectPageByMap(page,hashMap);
        return result;
    }

    //商家店长看到的订单列表
    //selectPageByMapYDForSeller
    @Override
    public IPage<HashMap<String,Object>> selectPageByMapYDForSeller(HashMap<String,Object> hashMap) {
        // Page<Map<String, Object>> page = new Page<>(currentPage, pageSize);
        Long t = Long.valueOf(hashMap.get("tenantid").toString());//前端传
        Long currentpage = Long.valueOf(hashMap.get("currentpage").toString());
        Integer pagesize = Integer.valueOf(hashMap.get("pagesize").toString());

        Page<HashMap<String, Object>> page = new Page<>(currentpage, pagesize);
        IPage<HashMap<String, Object>> result = mallOrderMapper.selectPageByMap(page,hashMap);
        if (result != null && result.getRecords() != null) {
            for (HashMap<String, Object> record : result.getRecords()) {
//                if (record.containsKey("create_time")) {
//                    String createTimeStr = (String) record.get("create_time");
//                    LocalDateTime createTime = LocalDateTime.parse(createTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
//                    record.put("create_time_txt", createTime);
//                }

                if (record.containsKey("create_time")) {
                    LocalDateTime createTime = (LocalDateTime) record.get("create_time");
                    String createTimeStr = createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    record.put("create_time_txt", createTimeStr);
                }
            }
        }
        //return mallOrderMapper.selectPageByMap(page,hashMap);
        return result;
    }

    //订单详情

    /**
     * 用户 不一定算
     * @param hashMap
     * @param
     * @return
     */
    @Override
    public HashMap<String, Object> selectMapByMap(HashMap<String, Object> hashMap) {

        HashMap<String, Object> result = mallOrderMapper.selectMapByMap(hashMap);
        if (result != null && result.containsKey("create_time")) {
            LocalDateTime createTime = (LocalDateTime) result.get("create_time");
            String createTimeStr = createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            result.put("create_time_txt", createTimeStr);
        }
        return result;
        //return mallOrderMapper.selectMapByMap(hashMap);
    }
    @Override
    public ResultModel<PrepayWithRequestPaymentResponse> newpay(HashMap<String, Object> hashMap) {


        MallWeChatPayVo inputMallWeChatPayVo = new MallWeChatPayVo();
        inputMallWeChatPayVo.setOpenId(hashMap.get("openid").toString());  //购买人的openid
        inputMallWeChatPayVo.setTenantId(1L); //支付的时候需要查

        String totalStr = hashMap.get("total").toString();
        int total = Integer.parseInt(totalStr);


        inputMallWeChatPayVo.setOrderNo(Long.valueOf(hashMap.get("openid").toString().toString()));
        inputMallWeChatPayVo.setTotal(total); //这个拉起微信的价格;
        //inputMallWeChatPayVo.setAttach(jsonString);//


        return iMallWxPayService.newpay(inputMallWeChatPayVo);
    }


    @Override
    public ResultModel<PrepayWithRequestPaymentResponse> addOrder(HashMap<String, Object> hashMap) {
        LoginUser loginUser = getLoginUser();
        //第一算出uid
        Long tenantid = loginUser.getTenantId();
        Long uid = loginUser.getId();
        if(tenantid == null){
            return null;
        }
        //todo 根据产品id 查产品属性相关 例如订单所需要的 规格名！ 分类名！ 自定义表单名!
//        MallProduct oneProduct = mallProductService.lambdaQuery().eq(MallProduct::getId, proid).one();
//        MallOrder mallOrder = new MallOrder();
//        mallOrderMapper.insert(mallOrder);
//        MallOrderDetails mallOrderDetails =new MallOrderDetails();
//        mallOrderDetailsMapper.insert(mallOrderDetails);

        //todo 0查询一个 产品表
        //todo 1插入一个order表
        //todo 2插入一个orderdetail 表

        Long productid = Long.valueOf(hashMap.get("productid").toString());//前端传
        Long pspecid = Long.valueOf(hashMap.get("pspecid").toString());//前端传
        Integer quantity = Integer.valueOf(hashMap.get("quantity").toString());//前端传

        MallProduct product = mallProductService.getById(productid); //产品id
        MallProductSpecification mallProductSpecification = mallProductSpecificationSerivce.getById(pspecid); //规格价格库存id;

        MallOrder mallOrder = new MallOrder();
        Long orderid = IdUtils.getSnowId();
        mallOrder.setId(orderid);
        mallOrder.setStatus(0); //未支付
        mallOrder.setTenantId(tenantid);

        if(!ObjectUtils.isEmpty(hashMap.get("formjson"))){
            mallOrder.setFormJson((String) hashMap.get("formjson")); //前端传一个formjson  自定义表单
        }
        //mallOrder.setCreateTime(new Date());  DB会自动不用管
        mallOrder.setUserId(uid); //lg bug
        // 计算总金额
        BigDecimal specValue = new BigDecimal(mallProductSpecification.getSpecValue());

        BigDecimal totalAmount = specValue.multiply(BigDecimal.valueOf(quantity));
        // 设置总金额
        mallOrder.setTotalAmount(totalAmount);

        mallOrderMapper.insert(mallOrder);
        MallOrderDetails mallOrderDetails = new MallOrderDetails();
        mallOrderDetails.setId(IdUtils.getSnowId());  //详情订单不是自增 居然
        mallOrderDetails.setOrderId(orderid);
        mallOrderDetails.setProductId(productid);
        BigDecimal price = new BigDecimal(mallProductSpecification.getSpecValue());
        mallOrderDetails.setPrice(price); //单价存一下
        mallOrderDetails.setSpecId(pspecid);
        //mallOrderDetails.setSpecName((String) hashMap.get("specname")); //前端传一个specname
        mallOrderDetails.setSpecName(mallProductSpecification.getSpecName()); // 自定规格【也可以查出来】
        mallOrderDetails.setUserId(uid);
        mallOrderDetails.setTenantId(tenantid);
        mallOrderDetails.setQuantity(quantity);
        mallOrderDetails.setProductTitle(product.getTitle());
//        JSONArray ja = JSON.parseArray(String.valueOf(product.getImages()));
        JSONObject j = (JSONObject) JSON.parse(String.valueOf(product.getImages()));
        String image1 = (String) j.get("image1");
        mallOrderDetails.setImageUrl(image1);     //一张图
        mallOrderDetailsMapper.insert(mallOrderDetails);

        //扣库存
        MallProductListDTO mallProductListDTO = new MallProductListDTO();
        mallProductListDTO.setId(pspecid); //根据主键吗？
        Integer oldStock = mallProductSpecification.getStock();
        Integer newStock = oldStock - quantity;
        mallProductListDTO.setStock(String.valueOf(newStock));
        iMallProductSpecificationSerivce.upadteProductStock(mallProductListDTO);

        OrderD orderD = new OrderD(orderid, 119, TimeUnit.SECONDS); // 1分钟的延迟
        orderD.setProductId(productid);
        orderD.setPspecId(pspecid);
        orderD.setQuantity(quantity);
        orderProcessor.addOrder(orderD);

        //【提交订单】为拉起支付做准备
        MallWeChatPayVo inputMallWeChatPayVo = new MallWeChatPayVo();
        /**
         *     "openId":"oKnDC5PMe5MJI7Owa0cxNCH5jcmQ",
         *     "orderNo":"osn0005",
         *     "goodsid":"113"
         */
        inputMallWeChatPayVo.setOrderNo(orderid);

        //DB查
//        MallUser user = iMallUserService.lambdaQuery()
//                .eq(MallUser::getUserId,uid)
//                .eq(MallUser::getTenantId, tenantid)
//                .one();

        SystemUsers systemUsers = iSystemUserService.lambdaQuery()
                .eq(SystemUsers::getId,uid)
                .eq(SystemUsers::getTenantId,tenantid)
                .eq(SystemUsers::getStatus,0)
                .eq(SystemUsers::getDeleted, 0)
                .one();

        //inputMallWeChatPayVo.setOpenId((String) hashMap.get("openId")); //前端必传openid
        inputMallWeChatPayVo.setOpenId(systemUsers.getOpenId());
        inputMallWeChatPayVo.setTenantId(tenantid); //支付的时候需要查
        //单价 * 数量 * 微信支付倍率
        BigDecimal sumTotalDecimal = specValue.multiply(BigDecimal.valueOf(quantity)).multiply(BigDecimal.valueOf(100));
//        Integer sumTotal = sumTotalDecimal.setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
        inputMallWeChatPayVo.setTotal(sumTotalDecimal.intValue()); //这个拉起微信的价格;

        String unjonsString = JSONObject.toJSONString(orderD);
        String jsonString = JSON.toJSONString(orderD);
        log.info("查看支付attach的string对象{}",jsonString);
        log.info("不常用查看支付attach的string对象{}",unjonsString);

        inputMallWeChatPayVo.setAttach(jsonString);

        return iMallWxPayService.prepayByJsapi(inputMallWeChatPayVo);
    }

    @Override
    public ResultModel<PrepayWithRequestPaymentResponse> goToPay(HashMap<String, Object> mallOrderVo) {
        Long orderid = Long.valueOf(mallOrderVo.get("orderid").toString());
        LoginUser loginUser = getLoginUser();
        //第一算出uid
        Long tenantid = loginUser.getTenantId();
        Long uid = loginUser.getId();


        MallWeChatPayVo inputMallWeChatPayVo = new MallWeChatPayVo();
        /**
         *     "openId":"oKnDC5PMe5MJI7Owa0cxNCH5jcmQ",
         *     "orderNo":"osn0005",
         *     "goodsid":"113"
         */
        SystemUsers systemUsers = iSystemUserService.lambdaQuery()
                .eq(SystemUsers::getId,uid)
                .eq(SystemUsers::getTenantId,tenantid)
                .eq(SystemUsers::getStatus,0)
                .eq(SystemUsers::getDeleted, 0)
                .one();

        //查 购买时的订单详情,order_detial （传还是查DB价格 则是最新的 客户不能享受 下单时的优惠）
        //传 则是下单时的优惠价格。

        //订单详情的单价 和 订单详情的数量


        MallOrderDetails mallOrderDetails = iMallOrderDetailService.lambdaQuery()
                        .eq(MallOrderDetails::getOrderId,orderid)
                                .one();

        inputMallWeChatPayVo.setOrderNo(orderid);
        inputMallWeChatPayVo.setOpenId(systemUsers.getOpenId());
        inputMallWeChatPayVo.setTenantId(tenantid); //支付的时候需要查
        //单价 * 数量 * 微信支付倍率
        //报错 Integer sumTotal = mallOrderDetails.getPrice() * mallOrderDetails.getQuantity() * 100;
        int quantity = mallOrderDetails.getQuantity();
        // 计算总价
        BigDecimal price = mallOrderDetails.getPrice();
        BigDecimal total = price.multiply(BigDecimal.valueOf(quantity)).multiply(BigDecimal.valueOf(100));
        // 设置精度并四舍五入
//        BigDecimal roundedTotal = total.setScale(0, RoundingMode.HALF_UP);

        //inputMallWeChatPayVo.setTotal(sumTotal); //这个拉起微信的价格;
        inputMallWeChatPayVo.setTotal(total.intValue());


        //不用放队列
        OrderD orderD = new OrderD(orderid, 119, TimeUnit.SECONDS); // 1分钟的延迟
        //注意打一下log
        orderD.setProductId(mallOrderDetails.getProductId());
        orderD.setPspecId(mallOrderDetails.getSpecId());
        orderD.setQuantity(mallOrderDetails.getQuantity());


        String unjonsString = JSONObject.toJSONString(orderD);
        String jsonString = JSON.toJSONString(orderD);
        log.info("查看支付attach的string对象{}",jsonString);
        log.info("不常用查看支付attach的string对象{}",unjonsString);

        inputMallWeChatPayVo.setAttach(jsonString);
        return iMallWxPayService.prepayByJsapi(inputMallWeChatPayVo);
    }

    @Override
    public HashMap<String, Object> findVeriUser(Long orderid) {
            //findVeriUser
        //HashMap<String, Object> result = mallOrderMapper.selectMapByMap(hashMap);
        HashMap<String,Object> hashMap = new HashMap<>();
        hashMap.put("orderid",orderid);
        return mallOrderMapper.findVeriUser(hashMap);
    }




}
